package indi.readbook.example.common.exception;

import java.util.List;

import javax.validation.ConstraintViolationException;
import indi.readbook.example.common.GlobalConstants;
import indi.readbook.example.common.res.ViewResult;
import org.apache.commons.lang3.exception.ExceptionUtils;
//import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;


import lombok.extern.slf4j.Slf4j;


@Slf4j
@Component
@RestControllerAdvice
public class ExceptionsHandler {

	static {
		log.info(".......................  异常处理器初始化 ");
	}
	
	@ExceptionHandler(IllegalStateException.class)
	@ResponseBody
	public Object illegalStateHandler(IllegalStateException e) {
		e.printStackTrace();
		log.error(GlobalConstants.SERVER_EXCEPTION_MESSAGE, ExceptionUtils.getStackTrace(e));
		return ViewResult.error(e.getMessage());
	}


	@ExceptionHandler(NotLoginException.class)
	@ResponseBody
	public Object notLoginExceptionHandler(NotLoginException e) {
		return ViewResult.noLogin(e.getMessage());
	}


	@ExceptionHandler(RuntimeException.class)
	@ResponseBody
	public Object runtimeHandler(RuntimeException e) {
		e.printStackTrace();
		log.error(GlobalConstants.SERVER_EXCEPTION_MESSAGE, ExceptionUtils.getStackTrace(e));
		return ViewResult.error(e.getMessage());
	}

	@ExceptionHandler(IndexOutOfBoundsException.class)
	@ResponseBody   
	public Object runtimeHandler(IndexOutOfBoundsException e) {
		e.printStackTrace();
		log.error(GlobalConstants.SERVER_EXCEPTION_MESSAGE,ExceptionUtils.getStackTrace(e));
		return ViewResult.error(e.getMessage());
	}

	@ExceptionHandler(BindException.class)
	public ViewResult handleBindException(BindException exception) {
		List<FieldError> allErrors = exception.getFieldErrors();
		StringBuilder sb = new StringBuilder();
		for (FieldError errorMessage : allErrors) {
			sb.append(errorMessage.getField()).append(": ").append(errorMessage.getDefaultMessage()).append(", ");
		}
		log.error(GlobalConstants.SERVER_EXCEPTION_MESSAGE,ExceptionUtils.getStackTrace(exception));
		return ViewResult.error(sb.toString());
	}

	@ExceptionHandler(ConstraintViolationException.class)
	public ViewResult handleBindException2(ConstraintViolationException exception) {
		String message = exception.getMessage();
		if (message.contains(".")) {
			String[] split = message.split("\\.");
			message = split[1];
		}
		log.error(GlobalConstants.SERVER_EXCEPTION_MESSAGE,ExceptionUtils.getStackTrace(exception));
		return ViewResult.error(message);
	}


//	@ExceptionHandler(NotFoundException.class)
//	public ViewResult handleBindException3(NotFoundException e) {
//		e.printStackTrace();
//		log.error(GlobalConstants.SERVER_EXCEPTION_MESSAGE, e.getMessage());
//		return ViewResult.error("网关找不到对应服务 请稍后再试 "+ExceptionUtils.getStackTrace(e));
//	}

	@ExceptionHandler(MethodArgumentNotValidException.class)
	public ViewResult handleBindException3(MethodArgumentNotValidException e) {
		e.printStackTrace();
		BindingResult bindingResult = e.getBindingResult();
		StringBuilder sb = new StringBuilder(bindingResult.getFieldErrors().size()*16);
		log.error(GlobalConstants.SERVER_EXCEPTION_MESSAGE, ExceptionUtils.getStackTrace(e));
		for (int i=0;i<bindingResult.getFieldErrors().size();i++){
			if(i>0){
				sb.append(",");
			}
			FieldError fieldError = bindingResult.getFieldErrors().get(i);
			sb.append(fieldError.getField()+":"+fieldError.getDefaultMessage());
		}
		return ViewResult.error(sb.toString());
	}
}
